import { PlayerManager } from './Biz/PlayerManager'
import { RoomManager } from './Biz/RoomManager'
import {
  ApiMsgEnum,
  IApiGameStartReq,
  IApiGameStartRes,
  IApiPlayerJoinReq,
  IApiPlayerJoinRes,
  IApiPlayerListReq,
  IApiPlayerListRes,
  IApiRoomCreateReq,
  IApiRoomCreateRes,
  IApiRoomJoinReq,
  IApiRoomJoinRes,
  IApiRoomLeaveRes,
  IApiRoomListReq,
  IApiRoomListRes
} from './Common'
import { Connection, MyServer } from './Core'
import { symlinkCommon } from './Utils'

symlinkCommon()

//
declare module './Core' {
  interface Connection {
    playerId: number
  }
}

const server = new MyServer({
  port: 8080
})

server.on('connection', () => {
  console.log('来人了', server.connections.size)
})

server.on('disconnection', (connection: Connection) => {
  console.log('走了', server.connections.size)
  if (connection.playerId) {
    PlayerManager.Instance.removePlayer(connection.playerId)
  }
  PlayerManager.Instance.syncPlayers()
  console.log('当前在线人数：', PlayerManager.Instance.players.size)
})

server.setApi(ApiMsgEnum.ApiPlayerJoin, (connection: Connection, data: IApiPlayerJoinReq): IApiPlayerJoinRes => {
  const { nickname } = data
  const player = PlayerManager.Instance.createPlayer({ nickname, connection })
  connection.playerId = player.id
  PlayerManager.Instance.syncPlayers()
  return {
    player: PlayerManager.Instance.getPlayerView(player)
  }
})

server.setApi(ApiMsgEnum.ApiPlayerList, (_connection: Connection, _data: IApiPlayerListReq): IApiPlayerListRes => {
  return {
    list: PlayerManager.Instance.getPlayersView()
  }
})

server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, _data: IApiRoomCreateReq): IApiRoomCreateRes => {
  // 判断玩家是否登录
  if (connection.playerId) {
    const newRoom = RoomManager.Instance.createRoom()
    const room = RoomManager.Instance.joinRoom(newRoom.id, connection.playerId)
    if (room) {
      PlayerManager.Instance.syncPlayers()
      RoomManager.Instance.syncRooms()
      return {
        room: RoomManager.Instance.getRoomView(room)
      }
    } else {
      throw new Error('房间不存在')
    }
  } else {
    throw new Error('未登录')
  }
})

server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, { rid }: IApiRoomJoinReq): IApiRoomJoinRes => {
  // 判断玩家是否登录
  if (connection.playerId) {
    const room = RoomManager.Instance.joinRoom(rid, connection.playerId)
    if (room) {
      PlayerManager.Instance.syncPlayers()
      RoomManager.Instance.syncRooms()
      RoomManager.Instance.syncRoom(room.id)
      return {
        room: RoomManager.Instance.getRoomView(room)
      }
    } else {
      throw new Error('房间不存在')
    }
  } else {
    throw new Error('未登录')
  }
})

server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection): IApiRoomLeaveRes => {
  // 判断玩家是否登录
  if (connection.playerId) {
    const player = PlayerManager.Instance.idMapPlayer.get(connection.playerId)
    if (player) {
      const rid = player.rid
      if (rid) {
        RoomManager.Instance.leaveRoom(rid, player.id)
        PlayerManager.Instance.syncPlayers()
        RoomManager.Instance.syncRooms()
        RoomManager.Instance.syncRoom(rid)
        return {}
      } else {
        throw new Error('玩家不在房间')
      }
    } else {
      throw new Error('玩家不存在')
    }
  } else {
    throw new Error('未登录')
  }
})

server.setApi(ApiMsgEnum.ApiRoomList, (_connection: Connection, _data: IApiRoomListReq): IApiRoomListRes => {
  return {
    list: RoomManager.Instance.getRoomsView()
  }
})

server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, _data: IApiGameStartReq): IApiGameStartRes => {
  if (connection.playerId) {
    const player = PlayerManager.Instance.idMapPlayer.get(connection.playerId)
    if (player) {
      const rid = player.rid
      if (rid) {
        RoomManager.Instance.startRoom(rid)
        PlayerManager.Instance.syncPlayers()
        RoomManager.Instance.syncRooms()
        RoomManager.Instance.syncRoom(rid)
        return {}
      } else {
        throw new Error('玩家不在房间')
      }
    } else {
      throw new Error('玩家不存在')
    }
  } else {
    throw new Error('未登录')
  }
})

server
  .start()
  .then(() => {
    console.log('服务启动成功，端口：8080')
  })
  .catch(err => {
    console.log('服务启动失败', err)
  })
